<template>
  <!-- 情况一：添加/修改 -->
  <el-table
    v-if="!isDetail && !isActivityComponent"
    :data="isBatch ? skuList : formData!.skus!"
    border
    class="tabNumWidth"
    max-height="500"
    size="small"
  >
    <el-table-column align="left" label="产品信息" min-width="150">
      <template #default="{ row }">
        <div class="flex items-center">
          <UploadImg v-model="row.picUrl" height="60px" width="60px" />
          <div class="flex flex-col ml-10px">
            <el-text type="info">建议尺寸：800x800</el-text>
            <div class="flex items-center">
              <div class="flex items-center" v-for="(item, index) in tableHeaders" :key="index">
                <span :title="item">{{ row.properties?.[index]?.valueName }}</span>
                <span v-if="index < row.properties?.length - 1"> ＋ </span>
              </div>
            </div>
          </div>
        </div>
      </template>
    </el-table-column>
    <!-- <template v-if="formData!.specType && !isBatch">
      <el-table-column
        v-for="(item, index) in tableHeaders"
        :key="index"
        :label="item.label"
        align="center"
        min-width="40"
      >
        <template #default="{ row }">
          {{ row.properties?.[index]?.valueName }}
        </template>
      </el-table-column>
    </template> -->
    <!-- <el-table-column align="center" label="条码" min-width="100">
      <template #default="{ row }">
        <el-input v-model="row.barCode" class="w-100%" />
      </template>
    </el-table-column> -->
    <el-table-column align="left" label="价格库存信息" min-width="300">
      <template #default="{ row }">
        <div class="flex flex-wrap gap-1">
          <div v-if="formData!.priceMode === 1">
            <el-input-number
              v-model="row.price"
              :min="0"
              :max="99999999"
              :step="1"
              controls-position="right"
              clearable
              class="!w-150px !md-w-220px"
            >
              <template #prefix>
                <el-tooltip content="即原价，是普通买家需要支付的费用">
                  <span><Icon icon="ep:info-filled" class="-bottom-3px" />销售价</span>
                </el-tooltip>
              </template>
              <template #suffix>
                <span>元</span>
              </template>
            </el-input-number>
          </div>
          <div v-if="formData!.priceMode === 1">
            <el-input-number
              v-model="row.vipPrice"
              :min="0"
              :max="99999999"
              :step="1"
              controls-position="right"
              clearable
              class="!w-150px !md-w-220px"
            >
              <template #prefix>
                <el-tooltip content="介于原价及成本价之间，是会员买家需要支付的费用">
                  <span><Icon icon="ep:info-filled" class="-bottom-3px" />会员价</span>
                </el-tooltip>
              </template>
              <template #suffix>
                <span>元</span>
              </template>
            </el-input-number>
          </div>
          <div v-if="formData!.priceMode === 1">
            <el-input-number
              v-model="row.costPrice"
              :min="0"
              :max="99999999"
              :step="1"
              controls-position="right"
              clearable
              class="!w-150px !md-w-220px"
            >
              <template #prefix>
                <el-tooltip content="用于自动计算积分或联盟豆抵扣数量">
                  <span><Icon icon="ep:info-filled" class="-bottom-3px" />成本价</span>
                </el-tooltip>
              </template>
              <template #suffix>
                <span>元</span>
              </template>
            </el-input-number>
          </div>
          <!-- <div v-if="formData!.priceMode === 1">
          <el-input-number
            v-model="row.marketPrice"
            :min="0"
            :max="99999999"
            :step="1"
            controls-position="right"
            clearable
            class="!w-150px !md-w-220px"
          >
            <template #prefix>
              <span>市场价：</span>
            </template>
            <template #suffix>
              <span>元</span>
            </template>
          </el-input>
        </div> -->
          <div>
            <el-input-number
              v-model="row.stock"
              :min="0"
              :max="99999999"
              :step="1"
              controls-position="right"
              clearable
              class="!w-150px !md-w-220px"
            >
              <template #prefix>
                <el-tooltip content="补货中或已售罄时请将库存设置为0">
                  <span><Icon icon="ep:info-filled" class="-bottom-3px" />库存</span>
                </el-tooltip>
              </template>
              <template #suffix>
                {{
                  formData!.stepQuantity && formData!.unitName
                    ? 'x' + formData!.stepQuantity + formData!.unitName
                    : ''
                }}
              </template>
            </el-input-number>
          </div>
          <div>
            <el-input-number
              v-model="row.weight"
              :min="formData!.priceMode === 1 ? 0 : formData!.stepQuantity"
              :max="formData!.priceMode === 1 ? 99999999 : formData!.stepQuantity"
              :step="1"
              controls-position="right"
              clearable
              class="!w-150px !md-w-220px"
            >
              <template #prefix>
                <el-tooltip content="用于计算配送费、运费及餐盒数量">
                  <span><Icon icon="ep:info-filled" class="-bottom-3px" />重量</span>
                </el-tooltip>
              </template>
              <template #suffix>
                <span>克</span>
              </template>
            </el-input-number>
          </div>
          <!-- <div>
            <el-input-number
              v-model="row.volume"
              :min="0"
              :max="99999999"
              :step="1"
              controls-position="right"
              clearable
              class="!w-150px !md-w-220px"
            >
              <el-tooltip content="用于计算配送费、运费">
                <span><Icon icon="ep:info-filled" class="-bottom-3px"/>体积</span>
              </el-tooltip>
              <template #suffix>
                <span>立方米</span>
              </template>
            </el-input-number>
          </div> -->
        </div>
      </template>
    </el-table-column>
    <el-table-column v-if="formData?.specType" align="center" fixed="right" label="操作" width="80">
      <template #default="{ row }">
        <el-button v-if="isBatch" link size="small" type="warning" @click="batchAdd">
          批量设置
        </el-button>
        <el-button
          v-else
          link
          size="small"
          type="danger"
          @click="deleteSku(row)"
          :disabled="Boolean(formData.id && (formData.id + '').length)"
          >删除
        </el-button>
      </template>
    </el-table-column>
  </el-table>

  <!-- 情况二：详情 -->
  <el-table
    v-if="isDetail"
    ref="activitySkuListRef"
    :data="formData!.skus!"
    border
    max-height="500"
    size="small"
    style="width: 99%"
    @selection-change="handleSelectionChange"
  >
    <el-table-column v-if="isComponent" type="selection" width="45" />
    <el-table-column align="left" label="产品信息" min-width="140">
      <template #default="{ row }">
        <div class="flex flex-col items-start">
          <el-image
            v-if="row.picUrl"
            :src="row.picUrl"
            class="h-50px w-50px"
            @click="imagePreview(row.picUrl)"
          />
          <span>{{ row.name || row.propertiesValue }}</span>
        </div>
      </template>
    </el-table-column>
    <!-- <template v-if="formData!.specType && !isBatch">
      <el-table-column
        v-for="(item, index) in tableHeaders"
        :key="index"
        :label="item.label"
        align="center"
        min-width="40"
      >
        <template #default="{ row }">
          {{ row.properties?.[index]?.valueName }}
        </template>
      </el-table-column>
    </template> -->
    <!-- <el-table-column align="center" label="条码" min-width="100">
      <template #default="{ row }">
        {{ row.barCode }}
      </template>
    </el-table-column> -->
    <el-table-column align="left" label="价格(元)" min-width="80">
      <template #default="{ row }">
        <p
          >销售价：<span class="text-orange-500">{{ fenToYuan(row.price) }}</span></p
        >
        <div>会员价：{{ fenToYuan(row.vipPrice) }}</div>
        <div>成本价：{{ fenToYuan(row.costPrice) }}</div>
        <div v-if="Number(row.wholesalePrice) > 0">批发价：{{ fenToYuan(row.wholesalePrice) }}</div>
        <!-- <div>市场价：{{ fenToYuan(row.marketPrice) }}</div> -->
        <!-- <div v-if="formData!.isBrokerage">一级返佣：{{ fenToYuan(row.firstBrokeragePrice) }}</div>
        <div v-if="formData!.isBrokerage">二级返佣：{{ fenToYuan(row.secondBrokeragePrice) }}</div> -->
      </template>
    </el-table-column>
    <el-table-column align="center" label="库存" min-width="40">
      <template #default="{ row }">
        {{ row.stock
        }}{{
          formData!.stepQuantity && formData!.unitName
            ? 'x' + formData!.stepQuantity + formData!.unitName
            : ''
        }}
      </template>
    </el-table-column>
  </el-table>

  <!-- 情况三：作为活动组件 -->
  <el-table
    v-if="isActivityComponent"
    :data="formData!.skus!"
    border
    max-height="500"
    size="small"
    style="width: 99%"
  >
    <el-table-column v-if="isComponent" type="selection" width="45" />
    <el-table-column label="产品信息" align="left" min-width="140" show-overflow-tooltip>
      <template #default="{ row }">
        <div class="flex flex-row items-start">
          <el-image
            :src="row.picUrl || '/placeholder.png'"
            class="h-30px w-30px"
            @click="imagePreview(row.picUrl || '/placeholder.png')"
          />
          <span class="ml-5px using-hidden">{{ row.name || row.propertiesValue }}</span>
        </div>
        <p
          >售价：<span class="text-orange-500">¥{{ fenToYuan(row.price) }}</span></p
        >
        <p
          >库存：{{ row.stock
          }}{{
            formData!.stepQuantity && formData!.unitName
              ? 'x' + formData!.stepQuantity + formData!.unitName
              : ''
          }}</p
        >
      </template>
    </el-table-column>
    <!-- <template v-if="formData!.specType">
      <el-table-column
        v-for="(item, index) in tableHeaders"
        :key="index"
        :label="item.label"
        align="center"
        min-width="40"
      >
        <template #default="{ row }">
          {{ row.properties?.[index]?.valueName }}
        </template>
      </el-table-column>
    </template> -->
    <!--  方便扩展每个活动配置的属性不一样  -->
    <slot name="extension"></slot>
  </el-table>
</template>
<script lang="ts" setup>
import { PropType, Ref } from 'vue'
import { copyValueToTarget, fenToYuan } from '@/utils'
import { propTypes } from '@/utils/propTypes'
import { UploadImg } from '@/components/UploadFile'
import type { Property, Sku, Spu } from '@/api/mall/product/spu'
import { createImageViewer } from '@/components/ImageViewer'
import { RuleConfig } from '@/views/mall/product/spu/components/index'
import { PropertyAndValues } from './index'
import { ElTable } from 'element-plus'
import { isEmpty } from '@/utils/is'

defineOptions({ name: 'SkuList' })
const message = useMessage() // 消息弹窗

const props = defineProps({
  propFormData: {
    type: Object as PropType<Spu>,
    default: () => {}
  },
  propertyList: {
    type: Array as PropType<PropertyAndValues[]>,
    default: () => []
  },
  ruleConfig: {
    type: Array as PropType<RuleConfig[]>,
    default: () => []
  },
  isBatch: propTypes.bool.def(false), // 是否作为批量操作组件
  isDetail: propTypes.bool.def(false), // 是否作为 sku 详情组件
  isComponent: propTypes.bool.def(false), // 是否作为 sku 选择组件
  isActivityComponent: propTypes.bool.def(false) // 是否作为 sku 活动配置组件
})
const formData: Ref<Spu | undefined> = ref<Spu>() // 表单数据
const skuList = ref<any>([
  {
    price: 0, // 销售价
    costPrice: 0, // 成本价
    marketPrice: 0, // 市场价
    wholesalePrice: 0, // 批发价
    vipPrice: 0, // 会员价
    barCode: '', // 产品条码
    picUrl: '', // 图片地址
    stock: 999, // 库存
    weight: 0, // 产品重量
    volume: 0, // 产品体积
    firstBrokeragePrice: 0, // 一级分销的佣金
    secondBrokeragePrice: 0 // 二级分销的佣金
  }
]) // 批量添加时的临时数据

/** 产品图预览 */
const imagePreview = (imgUrl: string) => {
  createImageViewer({
    zIndex: 9999999,
    urlList: [imgUrl]
  })
}

/** 批量添加 */
const batchAdd = () => {
  validateProperty()
  formData.value!.skus!.forEach((item) => {
    copyValueToTarget(item, skuList.value[0])
  })
}
/** 校验产品规格属性值 */
const validateProperty = () => {
  // 校验产品规格属性值是否为空，有一个为空都不给过
  const warningInfo = '存在属性属性值为空，请先检查完善属性值后重试！！！'
  for (const item of props.propertyList) {
    if (!item.values || isEmpty(item.values)) {
      message.warning(warningInfo)
      throw new Error(warningInfo)
    }
  }
}
/** 删除 sku */
const deleteSku = (row: Sku) => {
  const index = formData.value!.skus!.findIndex(
    // 直接把列表转成字符串比较
    (sku) => JSON.stringify(sku.properties) === JSON.stringify(row.properties)
  )
  formData.value!.skus!.splice(index, 1)
}
const tableHeaders = ref<any>([]) // 多属性表头
/**
 * 保存时，每个产品规格的表单要校验下。例如说，销售金额最低是 0.01 这种。
 */
const validateSku = () => {
  validateProperty()
  let warningInfo = ''
  let validate = true // 默认通过
  for (const sku of formData.value!.skus!) {
    // 作为活动组件的校验
    for (const rule of props?.ruleConfig) {
      const arg = getValue(sku, rule.name)
      if (!rule.rule(arg)) {
        validate = false // 只要有一个不通过则直接不通过
        warningInfo += rule.message
        break
      }
    }
    if (!warningInfo) {
      warningInfo = '请检查产品相关内容是否输入有效'
    }
    // 只要有一个不通过则结束后续的校验
    if (!validate) {
      message.warning(warningInfo)
      throw new Error(warningInfo)
    }
  }
}
const getValue = (obj: any, arg: any) => {
  const keys = arg.split('.')
  let value = obj
  for (const key of keys) {
    if (value && typeof value === 'object' && key in value) {
      value = value[key]
    } else {
      value = undefined
      break
    }
  }
  return value
}

const emit = defineEmits<{
  (e: 'selectionChange', value: Sku[]): void
}>()
/**
 * 选择时触发
 * @param Sku 传递过来的选中的 sku 是一个数组
 */
const handleSelectionChange = (val: Sku[]) => {
  emit('selectionChange', val)
}

/**
 * 将传进来的值赋值给 skuList
 */
watch(
  () => props.propFormData,
  (data) => {
    if (!data) return
    formData.value = data
  },
  {
    deep: true,
    immediate: true
  }
)

/** 生成表数据 */
const generateTableData = (propertyList: any[]) => {
  // 构建数据结构
  const propertyValues = propertyList.map((item) =>
    item.values.map((v: any) => ({
      propertyId: item.id,
      propertyName: item.name,
      valueId: v.id,
      valueName: v.name
    }))
  )
  const buildSkuList = build(propertyValues)
  // 如果回显的 sku 属性和添加的属性不一致则重置 skus 列表
  if (!validateData(propertyList)) {
    // 如果不一致则重置表数据，默认添加新的属性重新生成 sku 列表
    formData.value!.skus = []
  }
  for (const item of buildSkuList) {
    const row = {
      properties: Array.isArray(item) ? item : [item], // 如果只有一个属性的话返回的是一个 property 对象
      price: 0,
      costPrice: 0,
      marketPrice: 0,
      wholesalePrice: 0,
      vipPrice: 0,
      barCode: '',
      picUrl: '',
      stock: 999,
      weight: 0,
      volume: 0,
      firstBrokeragePrice: 0,
      secondBrokeragePrice: 0
    } as Sku
    // 如果存在属性相同的 sku 则不做处理
    const index = formData.value!.skus!.findIndex(
      (sku) => JSON.stringify(sku.properties) === JSON.stringify(row.properties)
    )
    if (index !== -1) {
      continue
    }
    formData.value!.skus!.push(row)
  }
}

/**
 * 生成 skus 前置校验（后续废弃规格项编号字段，故使用规格项名称而不是规格项编号来判断）
 */
const validateData = (propertyList: any[]) => {
  const skuPropertyNames: any = []
  formData.value!.skus!.forEach((sku) =>
    sku.properties
      ?.map((property) => property.propertyName)
      ?.forEach((propertyName) => {
        if (skuPropertyNames.indexOf(propertyName!) === -1) {
          skuPropertyNames.push(propertyName!)
        }
      })
  )
  const propertyNames = propertyList.map((item) => item.name)
  return skuPropertyNames.length === propertyNames.length
}

/** 构建所有排列组合 */
const build = (propertyValuesList: Property[][]) => {
  if (propertyValuesList.length === 0) {
    return []
  } else if (propertyValuesList.length === 1) {
    return propertyValuesList[0]
  } else {
    const result: any = []
    const rest = build(propertyValuesList.slice(1))
    for (let i = 0, m = propertyValuesList[0].length; i < m; i++) {
      for (let j = 0, n = rest.length; j < n; j++) {
        // 第一次不是数组结构，后面的都是数组结构
        if (Array.isArray(rest[j])) {
          result.push([propertyValuesList[0][i], ...rest[j]])
        } else {
          result.push([propertyValuesList[0][i], rest[j]])
        }
      }
    }
    return result
  }
}

/** 监听属性列表，生成相关参数和表头 */
watch(
  () => props.propertyList,
  (propertyList: PropertyAndValues[]) => {
    // 如果不是多规格则结束
    if (!formData.value!.specType) {
      return
    }
    // 如果当前组件作为批量添加数据使用，则重置表数据
    if (props.isBatch) {
      skuList.value = [
        {
          price: 0,
          costPrice: 0,
          marketPrice: 0,
          wholesalePrice: 0,
          vipPrice: 0,
          barCode: '',
          picUrl: '',
          stock: 999,
          weight: 0,
          volume: 0,
          firstBrokeragePrice: 0,
          secondBrokeragePrice: 0
        }
      ]
    }

    // 判断代理对象是否为空
    if (JSON.stringify(propertyList) === '[]') {
      return
    }
    // 重置表头
    tableHeaders.value = []
    // 生成表头
    propertyList.forEach((item, index) => {
      // name加属性项index区分属性值
      tableHeaders.value.push({ prop: `name${index}`, label: item.name })
    })
    // 如果回显的 sku 属性和添加的属性一致则不处理
    if (validateData(propertyList)) {
      return
    }
    // 添加新属性没有属性值也不做处理
    if (propertyList.some((item) => !item.values || isEmpty(item.values))) {
      return
    }
    // 生成 table 数据，即 sku 列表
    generateTableData(propertyList)
  },
  {
    deep: true,
    immediate: true
  }
)
const activitySkuListRef = ref<InstanceType<typeof ElTable>>()

const getSkuTableRef = () => {
  return activitySkuListRef.value
}
// 暴露出生成 sku 方法，给添加属性成功时调用
defineExpose({ generateTableData, validateSku, getSkuTableRef })
</script>
